#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>

const std::string sep = "\r\n";
// 添加报头
bool Encode(std::string &message)
{
    if (message.size() == 0)
    {
        return false;
    }
    std::string package = std::to_string(message.size()) + sep + message + sep;
    message = package;
    return true;
}
// 去掉报头  将从package中获取的正文部分写入到content中
bool Decode(std::string &package, std::string *content)
{
    // 必须要先满足长度条件,如果连长度条件都不满足就不可能是完整报文
    auto pos = package.find(sep);
    if (pos == std::string::npos)
    {
        return false;
    }
    std::string content_lenth_str = package.substr(0, pos);                     // 报头的长度
    int content_lenth = std::stoi(content_lenth_str);                           // 正文的长度
    int full_lenth = content_lenth_str.size() + content_lenth + 2 * sep.size(); // 完整报文的长度
    if (package.size() < full_lenth)
    {
        return false;
    }
    *content = package.substr(pos + sep.size(), content_lenth);
    package.erase(0, full_lenth); // 移除解析出来的一个完整报文
    return true;
}

class Request
{
public:
    Request()
        : _x(0), _y(0), _oper(0)
    {
    }
    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {
    }
    // 序列化
    bool Serizlize(std::string &out_message)
    {
        Json::Value root;
        // Key-value模式
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        // 建造者模式
        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_message = ss.str();
        return true;
    }
    // 反序列化
    bool Deserizlize(std::string &in_message)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingsuccessful = reader.parse(in_message, root);
        if (!parsingsuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt(); // 注意这里_oper虽然是char类型的,但是依旧要用asint,char类型实际上是ASCII码表的形式
        return true;
    }
    int X() const { return _x; }
    int Y() const { return _y; }
    char Oper() const { return _oper; }

    void Print()
    {
        std::cout << _x << std::endl;
        std::cout << _oper << std::endl;
        std::cout << _y << std::endl;
    }
    ~Request()
    {
    }

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response()
        : _result(0), _code(0)
    {
    }
    Response(int result, int code)
        : _result(result), _code(code)
    {
    }
    // 序列化
    bool Serizlize(std::string &out_message)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_message = ss.str();
        return true;
    }
    // 反序列化
    bool Deserizlize(std::string &in_message)
    {
        Json::Value root;
        Json::Reader reader;
        bool persingsuccessful = reader.parse(in_message, root);
        if (!persingsuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }
    int Result() const { return _result; }
    int Code() const { return _code; }

    void SetResult(int res) { _result = res; }
    void SetCode(int c) { _code = c; }
    ~Response()
    {
    }

private:
    int _result;
    int _code; // 出错码,只有为0时才表示结果时可靠的
};